<!DOCTYPE html>
<html>
  <head><meta name="generator" content="Hexo 3.8.0">
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  <meta name="description" content="火骑小龙龙づ博客 vue mint-ui js html css 前端">
  <meta name="keyword" content="hexo-theme, vuejs">
  
    <link rel="shortcut icon" href="/css/images/logo.png">
  
  <title>
    
      NextJs | 火骑小龙龙づ博客
    
  </title>
  <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <link href="//cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
  <link href="//cdn.bootcss.com/highlight.js/9.12.0/styles/tomorrow.min.css" rel="stylesheet">
  <link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/plugins/gitment.css">
  <script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
  <script src="//cdn.bootcss.com/geopattern/1.2.3/js/geopattern.min.js"></script>
  <script src="//cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js"></script>
  <script src="/js/qrious.js"></script>
<script src="/js/gitment.js"></script>
  
  
    <!-- MathJax support START -->
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <!-- MathJax support END -->
  


</head>
<div class="wechat-share">
  <img src="/css/images/logo.png">
</div>

  <body>
    <header class="header fixed-header">
  <div class="header-container">
    <a class="home-link" href="/">
      <div class="logo"></div>
      <span>火骑小龙龙づ博客</span>
    </a>
    <ul class="right-list">
      
        <li class="list-item">
          
            <a href="/" class="item-link">Home</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/tags" class="item-link">Tags</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/categories" class="item-link">Categories</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/archives" class="item-link">Archives</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/project" class="item-link">Project</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/about" class="item-link">About</a>
          
        </li>
      
    </ul>
    <div class="menu">
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </div>
    <div class="menu-mask">
      <ul class="menu-list">
        
          <li class="menu-item">
            
              <a href="/" class="menu-link">Home</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/tags" class="menu-link">Tags</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/categories" class="menu-link">Categories</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/archives" class="menu-link">Archives</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/project" class="menu-link">Project</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/about" class="menu-link">About</a>
            
          </li>
        
      </ul>
    </div>
  </div>
</header>


    <div id="article-banner">
  <h2>NextJs</h2>
  <p class="post-date">2019-09-20</p>
  <div class="arrow-down">
    <a href="javascript:;"></a>
  </div>
</div>
<main class="app-body flex-box">
  <!-- Article START -->
  <article class="post-article">
    <section class="markdown-content"><p>NextJs 一个前端小白的奋斗史</p>
<a id="more"></a>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* 手动搭建 */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* Next 作为 Koa的中间件 */</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>Koa </p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">(ctx,next) =&gt;&#123;</span><br><span class="line">    ctx.req, ctx.res <span class="comment">/* 是node原生的http中的属性 */</span></span><br><span class="line">    ctx.request, ctx.response <span class="comment">/* 是Koa Js 中封装的属性 */</span></span><br><span class="line"></span><br><span class="line">    ctx.set(<span class="string">"Content-Type"</span>, <span class="string">"application/json"</span>) </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>Redis </p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    添加环境变量 ---&gt; 复制到Redis安装目录到Path里面就可以了 </span></span><br><span class="line"><span class="comment">    检测Redis启动成功：redis-cli 打印出来的127.0.0.1：6379 代表redis启动成功</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    命令：</span></span><br><span class="line"><span class="comment">        keys * 查看所有的存储</span></span><br><span class="line"><span class="comment">        keys name 根据key名称查看</span></span><br><span class="line"><span class="comment">        set key value</span></span><br><span class="line"><span class="comment">        get key</span></span><br><span class="line"><span class="comment">        del key</span></span><br><span class="line"><span class="comment">        setex key time value  设置一个带有过期时间限制的value | time  过期时间 s为单位</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span>  </span><br><span class="line"><span class="string">`F:\Redis-x64-3.2.100`</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 设置密码 */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* requirepass foobared(123456) */</span></span><br><span class="line">auth <span class="number">123456</span> <span class="comment">/* 密码登录 */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* node 连接 redis  --  ioredis */</span></span><br><span class="line"></span><br><span class="line">npm i ioredis</span><br></pre></td></tr></table></figure>
<blockquote>
<p>Ant Design</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">npm install antd --save</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 按需加载 */</span></span><br><span class="line"></span><br><span class="line">npm install babel-plugin-<span class="keyword">import</span> </span><br><span class="line"></span><br><span class="line">$ touch .babelrc</span><br></pre></td></tr></table></figure>
<blockquote>
<p>NextJs</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/*  nextjs 默认不支持 import css */</span></span><br><span class="line"></span><br><span class="line">$ touch next.config.js <span class="comment">/* next 的配置文件 */</span></span><br><span class="line"></span><br><span class="line">$ npm i @zeit/next-css <span class="comment">/* 让 next 可以加载css */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 覆盖 next app */</span></span><br><span class="line">$ touch pages/_app.js</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    目录结构</span></span><br><span class="line"><span class="comment">    1. pages:</span></span><br><span class="line"><span class="comment">         一个文件 就对一个 路由页面 a.js   localhost:3000/a   </span></span><br><span class="line"><span class="comment">         pages/test/b.js  localhost:3000/test/a </span></span><br><span class="line"><span class="comment">    </span></span><br><span class="line"><span class="comment">    2. components 组件</span></span><br><span class="line"><span class="comment">    3. lib 功能型代码</span></span><br><span class="line"><span class="comment">    4. static 存放 css img icon 等</span></span><br><span class="line"><span class="comment">    5. .next </span></span><br><span class="line"><span class="comment">    6. next.config.js  配置文件</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<ul>
<li>Link 标签的传入的节点必须是唯一的</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">&lt;Link&gt;</span><br><span class="line">    &lt;div&gt;<span class="xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;<span class="regexp">/Link&gt;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">/</span>* err *<span class="regexp">/</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">&lt;Link&gt;</span></span><br><span class="line"><span class="regexp">    &lt;div&gt;&lt;/</span>div&gt;</span><br><span class="line">    &lt;span&gt;<span class="xml"><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line">&lt;<span class="regexp">/Link&gt;</span></span><br></pre></td></tr></table></figure>
<ul>
<li><p>路由携带信息只能用 query</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* http://localhost:3000/a?id=1 */</span></span><br><span class="line"><span class="keyword">import</span> Router <span class="keyword">from</span> <span class="string">'next/router'</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">goRouter</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    Router.push(&#123;</span><br><span class="line">        pathname: <span class="string">'/test/a'</span>,</span><br><span class="line">        query: &#123;</span><br><span class="line">            id: <span class="number">2</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* &lt;Button onClick=&#123;goRouter&#125;&gt;goRouter&lt;Button&gt; */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 接收参数 */</span></span><br><span class="line"><span class="keyword">import</span> &#123;withRouter&#125; <span class="keyword">from</span> <span class="string">'next/router'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> A = <span class="function">(<span class="params">&#123;router&#125;</span>) =&gt;</span> &lt;span&gt;&#123;router.query.id&#125;&lt;<span class="regexp">/span&gt;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">export default withRouter(A)</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>路由映射 改变路由的显示方式</p>
</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">原始路由 http://localhost:3000/a?id=1</span></span><br><span class="line"><span class="comment">理想录用 http://localhost:3000/a/1</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 方式1 */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* &lt;Link href='/test/a?id=1' as='/a/1' title='ABC'&gt;Link&lt;/Link&gt; */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 方式2 */</span></span><br><span class="line">Router.push(&#123;</span><br><span class="line">    pathname: <span class="string">'/test/a'</span>,</span><br><span class="line">    query: &#123;</span><br><span class="line">        id: <span class="number">2</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;, <span class="string">'test/a/2'</span>)</span><br></pre></td></tr></table></figure>
<ul>
<li>next 路由映射 解决 页面刷新 404</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* server.js */</span></span><br><span class="line"></span><br><span class="line"> router.get(<span class="string">'/a/:id'</span>, <span class="keyword">async</span> ctx =&gt; &#123;</span><br><span class="line">    <span class="keyword">const</span> id = ctx.params.id</span><br><span class="line">    <span class="keyword">await</span> handle(ctx.req, ctx.res, &#123;</span><br><span class="line">        pathname: <span class="string">'/a'</span>,</span><br><span class="line">        query: &#123; id &#125;,</span><br><span class="line">    &#125;)</span><br><span class="line">    ctx.respond = <span class="literal">false</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* a.js next 8 的版本这样写 */</span></span><br><span class="line"><span class="keyword">import</span> &#123;withRouter&#125; <span class="keyword">from</span> <span class="string">'next/router'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> A = <span class="function">(<span class="params">&#123;router&#125;</span>) =&gt;</span> &lt;span&gt;&#123;router.query.id&#125;&lt;<span class="regexp">/span&gt;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">export default withRouter(A)</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">/</span>* a.js next <span class="number">9</span>  *<span class="regexp">/</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">import &#123; withRouter &#125; from 'next/</span>router<span class="string">'</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">const Com = (&#123; router, query &#125;) =&gt; &#123;</span></span><br><span class="line"><span class="string">    // console.log(router)</span></span><br><span class="line"><span class="string">    console.log(query)</span></span><br><span class="line"><span class="string">    return &lt;span&gt;router.query.id：&#123;query.id&#125;&lt;/span&gt;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">/* next 9  */</span></span><br><span class="line"><span class="string">/* </span></span><br><span class="line"><span class="string">getInitialProps入参对象的属性如下：</span></span><br><span class="line"><span class="string">    pathname - URL 的 path 部分</span></span><br><span class="line"><span class="string">    query - URL 的 query 部分，并被解析成对象</span></span><br><span class="line"><span class="string">    asPath - 显示在浏览器中的实际路径（包含查询部分），为String类型</span></span><br><span class="line"><span class="string">    req - HTTP 请求对象 (只有服务器端有)</span></span><br><span class="line"><span class="string">    res - HTTP 返回对象 (只有服务器端有)</span></span><br><span class="line"><span class="string">    jsonPageRes - 获取数据响应对象 (只有客户端有)</span></span><br><span class="line"><span class="string">    err - 渲染过程中的任何错误</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    https://github.com/zeit/next.js/issues/8767 </span></span><br><span class="line"><span class="string">*/</span></span><br><span class="line"><span class="string">Com.getInitialProps = async (&#123; query &#125;) =&gt; &#123;</span></span><br><span class="line"><span class="string">    console.log(query)</span></span><br><span class="line"><span class="string">    return &#123; query &#125;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">export default withRouter(Com)</span></span><br></pre></td></tr></table></figure>
<ul>
<li>next 路由 钩子</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    history 模式</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    'routeChangeStart'      1. 路由开始变化  toPath</span></span><br><span class="line"><span class="comment">    'routeChangeComplete'   3. 模块变化</span></span><br><span class="line"><span class="comment">    'routeChangeError'</span></span><br><span class="line"><span class="comment">    'beforeHistoryChange'   2. 使用的是historyApi所以history 变化</span></span><br><span class="line"><span class="comment">    'hashChangeStart'</span></span><br><span class="line"><span class="comment">    'hashChangeComplete'</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    hash 模式</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    'routeChangeStart' </span></span><br><span class="line"><span class="comment">    'routeChangeComplete' </span></span><br><span class="line"><span class="comment">    'routeChangeError'</span></span><br><span class="line"><span class="comment">    'beforeHistoryChange' </span></span><br><span class="line"><span class="comment">    'hashChangeStart'       1. 路由开始变化  toPath</span></span><br><span class="line"><span class="comment">    'hashChangeComplete'    2. 模块变化</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    'routeChangeError' 路由变化错误</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<ul>
<li>next 获取数据的方法 <code>getInitialProps</code></li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    getInitialProps是挂在组件上的一个静态方法，完成数据获取，在进入页面时提前获取数据，或者在app（_app.js）中获取全局的数据，完成客户端和服务端的数据同步</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    next获取数据的规范，获取数据尽量放在getInitialProps中</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    1. 只有在pages中才可以被调用，components中是不起做用的</span></span><br><span class="line"><span class="comment">    </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line">Com.getInitialProps = <span class="keyword">async</span> (&#123; query &#125;) =&gt; &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123; query &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* </span></span><br><span class="line"><span class="comment">        return 的数据都会被放在props中</span></span><br><span class="line"><span class="comment">    </span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>next 自定义app.js</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="number">1.</span> 固定 Layout</span><br><span class="line"><span class="number">2.</span> 保持一些公用的状态</span><br><span class="line"><span class="number">3.</span> 给页面传一些自定义的数据</span><br><span class="line"></span><br><span class="line"><span class="comment">/* next8 */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> App, &#123; Container &#125; <span class="keyword">from</span> <span class="string">'next/app'</span>;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyApp</span> <span class="keyword">extends</span> <span class="title">App</span> </span>&#123;</span><br><span class="line">    render() &#123;</span><br><span class="line">        <span class="keyword">const</span> &#123; Component &#125; = <span class="keyword">this</span>.props</span><br><span class="line">        <span class="keyword">return</span> (</span><br><span class="line">            &lt;Container&gt;</span><br><span class="line">                &lt;Component /&gt;</span><br><span class="line">            &lt;<span class="regexp">/Container&gt;</span></span><br><span class="line"><span class="regexp">        )</span></span><br><span class="line"><span class="regexp">    &#125;</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br><span class="line"><span class="regexp">export default MyApp;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">/</span>* next9 *<span class="regexp">/</span></span><br><span class="line"><span class="regexp">/</span>* the <span class="string">`Container`</span> <span class="keyword">in</span> <span class="string">`_app`</span> has been deprecated and should be removed</span><br><span class="line"><span class="string">`_app`</span>中的<span class="string">`Container`</span>已被弃用，应予以删除 *<span class="regexp">/</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">import App from 'next/</span>app<span class="string">';</span></span><br><span class="line"><span class="string">class MyApp extends App &#123;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    static async getInitialProps(&#123; Component, ctx &#125;) &#123;</span></span><br><span class="line"><span class="string">        /* 每次页面切换 该方法都会被执行 */</span></span><br><span class="line"><span class="string">        /*</span></span><br><span class="line"><span class="string">            &#123;</span></span><br><span class="line"><span class="string">                AppTree: [Function: AppTree],</span></span><br><span class="line"><span class="string">                Component: [Function],</span></span><br><span class="line"><span class="string">                router: ServerRouter &#123;</span></span><br><span class="line"><span class="string">                    route: '</span>/<span class="string">',</span></span><br><span class="line"><span class="string">                    pathname: '</span>/<span class="string">',</span></span><br><span class="line"><span class="string">                    query: [Object: null prototype] &#123;&#125;,</span></span><br><span class="line"><span class="string">                    asPath: '</span>/<span class="string">'</span></span><br><span class="line"><span class="string">                &#125;,</span></span><br><span class="line"><span class="string">                ctx &#123;</span></span><br><span class="line"><span class="string">                    err</span></span><br><span class="line"><span class="string">                    req,</span></span><br><span class="line"><span class="string">                    res,</span></span><br><span class="line"><span class="string">                    pathname: '</span>/<span class="string">',</span></span><br><span class="line"><span class="string">                    query: [Object: null prototype] &#123;&#125;,</span></span><br><span class="line"><span class="string">                    asPath: '</span>/<span class="string">',</span></span><br><span class="line"><span class="string">                    AppTree: [Function: AppTree]</span></span><br><span class="line"><span class="string">                &#125; </span></span><br><span class="line"><span class="string">            &#125;        </span></span><br><span class="line"><span class="string">        */</span></span><br><span class="line"><span class="string">        let pageProps = &#123;&#125;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">        if (Component.getInitialProps) &#123;</span></span><br><span class="line"><span class="string">            pageProps = await Component.getInitialProps(ctx)</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">        return &#123; pageProps &#125;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    render() &#123;</span></span><br><span class="line"><span class="string">        const &#123; Component, pageProps &#125; = this.props</span></span><br><span class="line"><span class="string">        return &lt;Component &#123;...pageProps&#125; /&gt;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">export default MyApp;</span></span><br></pre></td></tr></table></figure>
<ul>
<li>next 自定义document</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="number">1.</span> 只有在服务端渲染的时候被调用</span><br><span class="line"><span class="number">2.</span> 用来修改服务端渲染的文档内容</span><br><span class="line"></span><br><span class="line"><span class="comment">/* $ touch pages/_document.js */</span></span><br><span class="line"><span class="keyword">import</span> Document, &#123; Html, Head, Main, NextScript &#125; <span class="keyword">from</span> <span class="string">'next/document'</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyDocument</span> <span class="keyword">extends</span> <span class="title">Document</span> </span>&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">async</span> getInitialProps(ctx) &#123;</span><br><span class="line">        <span class="comment">/* </span></span><br><span class="line"><span class="comment">            &#123;</span></span><br><span class="line"><span class="comment">                err,</span></span><br><span class="line"><span class="comment">                req,</span></span><br><span class="line"><span class="comment">                res,</span></span><br><span class="line"><span class="comment">                pathname: '/a',</span></span><br><span class="line"><span class="comment">                query: &#123;</span></span><br><span class="line"><span class="comment">                    id: '2'</span></span><br><span class="line"><span class="comment">                &#125;,</span></span><br><span class="line"><span class="comment">                asPath: '/a/2',</span></span><br><span class="line"><span class="comment">                AppTree: [Function: AppTree],</span></span><br><span class="line"><span class="comment">                renderPage: [Function: renderPage]</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">        <span class="keyword">const</span> initialProps = <span class="keyword">await</span> Document.getInitialProps(ctx)</span><br><span class="line">        <span class="keyword">return</span> &#123; ...initialProps &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    render() &#123;</span><br><span class="line">        <span class="keyword">return</span> (</span><br><span class="line">            &lt;Html&gt;</span><br><span class="line">                &lt;Head&gt;</span><br><span class="line">                    &lt;title&gt;My App&lt;<span class="regexp">/title&gt;</span></span><br><span class="line"><span class="regexp">                    &#123;/</span>* &lt;title&gt; should not be used in _document.js's &lt;Head&gt; */&#125;</span><br><span class="line">                    &lt;style&gt;&#123;`</span><br><span class="line">                        .test &#123;</span><br><span class="line">                            color: red</span><br><span class="line">                        &#125;</span><br><span class="line">                    `&#125;&lt;/style&gt;</span><br><span class="line"><span class="xml">                <span class="tag">&lt;/<span class="name">Head</span>&gt;</span></span></span><br><span class="line">                &lt;body className="test"&gt;</span><br><span class="line">                    &lt;Main /&gt;</span><br><span class="line">                    &lt;NextScript /&gt;</span><br><span class="line"><span class="xml">                <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span></span><br><span class="line"><span class="xml">            <span class="tag">&lt;/<span class="name">Html</span>&gt;</span></span></span><br><span class="line">        )</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> MyDocument</span><br></pre></td></tr></table></figure>
<ul>
<li>next 中修改 Head </li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> Head <span class="keyword">from</span> <span class="string">'next/head'</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">IndexPage</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">      &lt;Head&gt;</span><br><span class="line">        &lt;title&gt;My page title&lt;<span class="regexp">/title&gt;</span></span><br><span class="line"><span class="regexp">        &lt;meta</span></span><br><span class="line"><span class="regexp">          name="viewport"</span></span><br><span class="line"><span class="regexp">          content="initial-scale=1.0, width=device-width"</span></span><br><span class="line"><span class="regexp">          key="viewport"</span></span><br><span class="line"><span class="regexp">        /</span>&gt;</span><br><span class="line">      &lt;<span class="regexp">/Head&gt;</span></span><br><span class="line"><span class="regexp">      &lt;Head&gt;</span></span><br><span class="line"><span class="regexp">        &lt;meta</span></span><br><span class="line"><span class="regexp">          name="viewport"</span></span><br><span class="line"><span class="regexp">          content="initial-scale=1.2, width=device-width"</span></span><br><span class="line"><span class="regexp">          key="viewport"</span></span><br><span class="line"><span class="regexp">        /</span>&gt;</span><br><span class="line">      &lt;<span class="regexp">/Head&gt;</span></span><br><span class="line"><span class="regexp">      &lt;p&gt;Hello world!&lt;/</span>p&gt;</span><br><span class="line">    &lt;<span class="regexp">/div&gt;</span></span><br><span class="line"><span class="regexp">  )</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">export default IndexPage</span></span><br></pre></td></tr></table></figure>
<ul>
<li>next 样式</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* github style-jsx */</span></span><br><span class="line"><span class="keyword">const</span> lineHeight = <span class="string">'50px'</span></span><br><span class="line"><span class="keyword">const</span> Com = <span class="function">(<span class="params">&#123; router, query &#125;</span>) =&gt;</span> (</span><br><span class="line">    &lt;&gt;</span><br><span class="line">        &lt;span&gt;router.query.id：&#123;query.id&#125;&lt;<span class="regexp">/span&gt;</span></span><br><span class="line"><span class="regexp">        &lt;style jsx&gt;&#123;`</span></span><br><span class="line"><span class="regexp">            span &#123;</span></span><br><span class="line"><span class="regexp">                color: red;</span></span><br><span class="line"><span class="regexp">                line-height: $&#123;lineHeight&#125;</span></span><br><span class="line"><span class="regexp">            &#125;</span></span><br><span class="line"><span class="regexp">        `&#125;&lt;/</span>style&gt;</span><br><span class="line">    &lt;<span class="regexp">/&gt;</span></span><br><span class="line"><span class="regexp">)</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">/</span>*  全局样式 但只在当前设置的组件被渲染的时候生效 *<span class="regexp">/</span></span><br><span class="line"><span class="regexp">&lt;style jsx global&gt;&#123;``&#125;&lt;/</span>style&gt;</span><br></pre></td></tr></table></figure>
<ul>
<li>next 集成styled-components</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* $ npm i styled-components babel-plugin-styled-components */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* _document.js */</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">async</span> getInitialProps(ctx) &#123;</span><br><span class="line">    <span class="keyword">const</span> originalRenderPage = ctx.renderPage</span><br><span class="line">    <span class="keyword">const</span> sheet = <span class="keyword">new</span> ServerStyleSheet()</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        ctx.renderPage = <span class="function"><span class="params">()</span> =&gt;</span> originalRenderPage(&#123;</span><br><span class="line">            <span class="comment">// enhanceApp: App =&gt; App,</span></span><br><span class="line">            <span class="comment">// enhanceApp: App =&gt; Log(App),</span></span><br><span class="line">            enhanceApp: <span class="function"><span class="params">App</span> =&gt;</span> (props) =&gt; sheet.collectStyles(<span class="xml"><span class="tag">&lt;<span class="name">App</span> &#123;<span class="attr">...props</span>&#125; /&gt;</span>),</span></span><br><span class="line"><span class="xml">            // enhanceComponent: Component =&gt; Log(Component),</span></span><br><span class="line"><span class="xml">        &#125;)</span></span><br><span class="line"><span class="xml">        const initialProps = await Document.getInitialProps(ctx)</span></span><br><span class="line"><span class="xml">        return &#123;</span></span><br><span class="line"><span class="xml">            ...initialProps,</span></span><br><span class="line"><span class="xml">            styles:(</span></span><br><span class="line"><span class="xml">                <span class="tag">&lt;&gt;</span>&#123;initialProps.styles&#125;&#123;sheet.getStyleElement()&#125;<span class="tag">&lt;/&gt;</span></span></span><br><span class="line"><span class="xml">            ),</span></span><br><span class="line"><span class="xml">            /* </span></span><br><span class="line"><span class="xml">                initialProps.styles: 是next内置的 style-jsx 产生的样式</span></span><br><span class="line"><span class="xml">            </span></span><br><span class="line"><span class="xml">            */</span></span><br><span class="line"><span class="xml">        &#125;</span></span><br><span class="line"><span class="xml">    &#125; finally &#123;</span></span><br><span class="line"><span class="xml">        sheet.seal()</span></span><br><span class="line"><span class="xml">    &#125;</span></span><br><span class="line"><span class="xml">&#125;</span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">/* pages/a.js */</span></span><br><span class="line"><span class="xml">const Title = styled.h1`</span></span><br><span class="line"><span class="xml">    color: green</span></span><br><span class="line"><span class="xml">`</span></span><br><span class="line"><span class="xml"><span class="tag">&lt;<span class="name">Title</span>&gt;</span>123<span class="tag">&lt;/<span class="name">Title</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<ul>
<li>next 异步模块和组件加载 <code>LazyLoading</code></li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="number">1.</span> 异步加载模块</span><br><span class="line"><span class="number">2.</span> 异步加载组件</span><br><span class="line"></span><br><span class="line"><span class="comment">/*$ npm i moment */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 加载模块 */</span></span><br><span class="line"><span class="keyword">import</span> moment <span class="keyword">from</span> <span class="string">'moment'</span> <span class="comment">/* 一次性加载 */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* or */</span></span><br><span class="line"></span><br><span class="line">Com.getInitialProps = <span class="keyword">async</span> (&#123; query &#125;) =&gt; &#123;</span><br><span class="line">    <span class="keyword">const</span> moment =  <span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">'moment'</span>) <span class="comment">/* 异步加载模块 */</span></span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        query,</span><br><span class="line">        time: moment.default(<span class="built_in">Date</span>.now() - <span class="number">60</span>*<span class="number">1000</span>).fromNow()</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 异步加载组件 */</span></span><br><span class="line"><span class="keyword">import</span> dynamic <span class="keyword">from</span> <span class="string">'next/dynamic'</span></span><br><span class="line"><span class="keyword">const</span> Comp = dynamic(<span class="keyword">import</span>(<span class="string">'../components/Com'</span>))</span><br></pre></td></tr></table></figure>
<ul>
<li>next 中的配置</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* next.config.js */</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">// 编译文件的输出目录</span></span><br><span class="line">    distDir: <span class="string">'dest'</span>,</span><br><span class="line">    <span class="comment">// 是否给每个路由生成Etag</span></span><br><span class="line">    generateEtags: <span class="literal">true</span>,</span><br><span class="line">    <span class="comment">// 页面内容缓存配置</span></span><br><span class="line">    onDemandEntries: &#123;</span><br><span class="line">        <span class="comment">// 内容在内存中缓存的时长（ms）</span></span><br><span class="line">        maxInactiveAge: <span class="number">25</span> * <span class="number">1000</span>,</span><br><span class="line">        <span class="comment">// 同时缓存多少个页面</span></span><br><span class="line">        pagesBufferLength: <span class="number">2</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">// 在pages目录下那种后缀的文件会被认为是页面</span></span><br><span class="line">    pageExtensions: [<span class="string">'jsx'</span>, <span class="string">'js'</span>],</span><br><span class="line">    <span class="comment">// 配置buildId</span></span><br><span class="line">    generateBuildId: <span class="keyword">async</span> () =&gt; &#123;</span><br><span class="line">        <span class="keyword">if</span> (process.env.YOUR_BUILD_ID) &#123;</span><br><span class="line">            <span class="keyword">return</span> process.env.YOUR_BUILD_ID</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 返回null使用默认的unique id</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">// 手动修改webpack config</span></span><br><span class="line">    webpack(config, options) &#123;</span><br><span class="line">        <span class="keyword">return</span> config</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">// 修改webpackDevMiddleware配置</span></span><br><span class="line">    webpackDevMiddleware: <span class="function"><span class="params">config</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> config</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">// 可以在页面上通过 procsess.env.customKey 获取 value</span></span><br><span class="line">    env: &#123;</span><br><span class="line">        customKey: <span class="string">'value'</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">// 下面两个要通过 'next/config' 来读取</span></span><br><span class="line">    <span class="comment">// 只有在服务端渲染时才会获取的配置</span></span><br><span class="line">    serverRuntimeConfig: &#123;</span><br><span class="line">        mySecret: <span class="string">'secret'</span>,</span><br><span class="line">        secondSecret: process.env.SECOND_SECRET,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">// 在服务端渲染和客户端渲染都可获取的配置</span></span><br><span class="line">    publicRuntimeConfig: &#123;</span><br><span class="line">        staticFolder: <span class="string">'/static'</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    serverRuntimeConfig, publicRuntimeConfig</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    需要使用 import getConfig from 'next/config' 模块来获取</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    const &#123;serverRuntimeConfig, publicRuntimeConfig&#125; = getConfig()</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<ul>
<li>next Hoc模式</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* 接收组件作为参数并返回新的组件  react-redux中的connect */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> (Comp) =&gt; &#123;</span><br><span class="line">    <span class="comment">// return function TestHocComp(props) &#123;</span></span><br><span class="line">    <span class="comment">//     return &lt;Comp &#123;...props&#125; /&gt;</span></span><br><span class="line">    <span class="comment">// &#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// return function TestHocComp(&#123; name, rest &#125;) &#123;</span></span><br><span class="line">    <span class="comment">//     /* 预处理 name */</span></span><br><span class="line">    <span class="comment">//     const name1 = name + 123;</span></span><br><span class="line">    <span class="comment">//     return &lt;Comp &#123;...rest&#125; name=&#123;name1&#125; /&gt;</span></span><br><span class="line">    <span class="comment">// &#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">TestHocComp</span>(<span class="params">&#123; Component, pageProps, ...rest &#125;</span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(Component, pageProps)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (pageProps) &#123;</span><br><span class="line">            pageProps.test = <span class="string">'123'</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">Comp</span> <span class="attr">Component</span>=<span class="string">&#123;Component&#125;</span> <span class="attr">pageProps</span>=<span class="string">&#123;pageProps&#125;</span> &#123;<span class="attr">...rest</span>&#125; /&gt;</span></span></span><br><span class="line"><span class="xml">    &#125;</span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">    /* 注意地方 */</span></span><br><span class="line"><span class="xml">    TestHocComp.getInitialProps = Comp.getInitialProps</span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">    return TestHocComp</span></span><br><span class="line"><span class="xml">&#125;</span></span><br></pre></td></tr></table></figure>
<ul>
<li>next 中集成 redux</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* 服务端如何写入数据到store */</span></span><br><span class="line"><span class="comment">/* 如何同步服务端的数据到客户端 */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* store.js */</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="function"><span class="keyword">function</span> <span class="title">initializeStore</span>(<span class="params">state</span>) </span>&#123;</span><br><span class="line">    <span class="comment">/* 导出一个Func在render中调用，保证每一次的store都是新的 */</span></span><br><span class="line">    <span class="keyword">const</span> store = createStore(</span><br><span class="line">        combineReducers(&#123;</span><br><span class="line">            count: reducer,</span><br><span class="line">            user: userReducer</span><br><span class="line">        &#125;),</span><br><span class="line">        <span class="built_in">Object</span>.assign(&#123;&#125;, &#123;</span><br><span class="line">            count: initialState,</span><br><span class="line">            user: userInitialState</span><br><span class="line">        &#125;, state),</span><br><span class="line">        composeWithDevTools(applyMiddleware(reduxThunk))</span><br><span class="line">    )</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> store</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* with-redux */</span></span><br><span class="line"><span class="keyword">import</span> React <span class="keyword">from</span> <span class="string">'react'</span></span><br><span class="line"><span class="keyword">import</span> creatStore <span class="keyword">from</span> <span class="string">'../store/store'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> isServer = <span class="keyword">typeof</span> <span class="built_in">window</span> === <span class="string">"undefined"</span></span><br><span class="line"><span class="keyword">const</span> __NRXT_REDUX_STORE__ = <span class="string">"__NRXT_REDUX_STORE__"</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 单例 模式 保证 store唯一 */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getOrCreateStore</span>(<span class="params">initialState</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (isServer) &#123;</span><br><span class="line">        <span class="keyword">return</span> creatStore(initialState)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!<span class="built_in">window</span>[__NRXT_REDUX_STORE__]) &#123;</span><br><span class="line">        <span class="built_in">window</span>[__NRXT_REDUX_STORE__] = creatStore(initialState)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">window</span>[__NRXT_REDUX_STORE__]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> (Comp) =&gt; &#123;</span><br><span class="line">    <span class="class"><span class="keyword">class</span> <span class="title">WithReduxApp</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span> </span>&#123;</span><br><span class="line">        <span class="keyword">constructor</span>(props) &#123;</span><br><span class="line">            <span class="keyword">super</span>(props)</span><br><span class="line">            <span class="keyword">this</span>.reduxStore = getOrCreateStore(props.initialReduxState)</span><br><span class="line">        &#125;</span><br><span class="line">        render() &#123;</span><br><span class="line">            <span class="keyword">const</span> &#123; Component, pageProps, ...rest &#125; = <span class="keyword">this</span>.props</span><br><span class="line">            <span class="keyword">if</span> (pageProps) &#123;</span><br><span class="line">                pageProps.test = <span class="string">'123'</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">Comp</span> <span class="attr">Component</span>=<span class="string">&#123;Component&#125;</span> <span class="attr">pageProps</span>=<span class="string">&#123;pageProps&#125;</span> &#123;<span class="attr">...rest</span>&#125; <span class="attr">reduxStore</span>=<span class="string">&#123;this.reduxStore&#125;</span> /&gt;</span></span></span><br><span class="line"><span class="xml">        &#125;</span></span><br><span class="line"><span class="xml">    &#125;</span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">    /* 注意地方 */</span></span><br><span class="line"><span class="xml">    /* TestHocComp.getInitialProps = Comp.getInitialProps */</span></span><br><span class="line"><span class="xml">    WithReduxApp.getInitialProps = async (ctx) =&gt; &#123;</span></span><br><span class="line"><span class="xml">        const reduxStore = getOrCreateStore()</span></span><br><span class="line"><span class="xml">        ctx.reduxStore = reduxStore</span></span><br><span class="line"><span class="xml">        let appProps = &#123;&#125;</span></span><br><span class="line"><span class="xml">        if (typeof Comp.getInitialProps === "function") &#123;</span></span><br><span class="line"><span class="xml">            appProps = await Comp.getInitialProps(ctx)</span></span><br><span class="line"><span class="xml">        &#125;</span></span><br><span class="line"><span class="xml">        return &#123;</span></span><br><span class="line"><span class="xml">            ...appProps,</span></span><br><span class="line"><span class="xml">            initialReduxState: reduxStore.getState()</span></span><br><span class="line"><span class="xml">        &#125;</span></span><br><span class="line"><span class="xml">    &#125;</span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">    return WithReduxApp</span></span><br><span class="line"><span class="xml">&#125;</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>Hooks </p>
</blockquote>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">import</span> React, &#123; useState, useEffect &#125; <span class="keyword">from</span> <span class="string">'react'</span></span><br><span class="line"><span class="comment">/* React */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyCount</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span> </span>&#123;</span><br><span class="line">    state = &#123;</span><br><span class="line">        count: <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    componentDidMount() &#123;</span><br><span class="line">        <span class="keyword">this</span>.interval = setInterval(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">this</span>.setState(&#123;</span><br><span class="line">                count: <span class="keyword">this</span>.state.count + <span class="number">1</span></span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;, <span class="number">1000</span>)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    componentWillUnmount() &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span>.interval) &#123;</span><br><span class="line">            clearInterval(<span class="keyword">this</span>.interval)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    render() &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">span</span>&gt;</span>&#123;this.state.count&#125;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/*React  Hooks */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">MyCountFunc</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">const</span> [count, setCount] = useState(<span class="number">0</span>)</span><br><span class="line"></span><br><span class="line">    useEffect(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> interval = setInterval(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">            setCount(count + <span class="number">1</span>)</span><br><span class="line">        &#125;, <span class="number">1000</span>)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="params">()</span> =&gt;</span> clearInterval(interval)</span><br><span class="line">    &#125;, [count])</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* or */</span></span><br><span class="line"></span><br><span class="line">    </span><br><span class="line">    useEffect(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> interval = setInterval(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">            setCount(<span class="function"><span class="params">count</span> =&gt;</span>count + <span class="number">1</span>)</span><br><span class="line">        &#125;, <span class="number">1000</span>)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="params">()</span> =&gt;</span> clearInterval(interval)</span><br><span class="line">    &#125;, [])</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">span</span>&gt;</span>&#123;count&#125;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// export default MyCount</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> MyCountFunc</span><br></pre></td></tr></table></figure>
<ul>
<li>Hooks –&gt; State</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* API: useState */</span></span><br><span class="line"><span class="keyword">import</span> React, &#123; useState, useEffect &#125; <span class="keyword">from</span> <span class="string">'react'</span></span><br><span class="line"><span class="keyword">const</span> [state, setState] = useState(<span class="number">0</span>) <span class="comment">/* state: 0 */</span></span><br><span class="line">setState(<span class="number">1</span>) <span class="comment">/* state: 1 */</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* API: useReducer */</span></span><br><span class="line"><span class="keyword">import</span> React, &#123; useState, useEffect, useReducer &#125; <span class="keyword">from</span> <span class="string">'react'</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">MyCountFunc</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// const [count, setCount] = useState(0)</span></span><br><span class="line">    <span class="keyword">const</span> [count, dispatchCount] = useReducer(countReducer, <span class="number">0</span>)</span><br><span class="line"></span><br><span class="line">    useEffect(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> interval = setInterval(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">            <span class="comment">// setCount(count =&gt; count + 1)</span></span><br><span class="line">            dispatchCount(&#123; <span class="attr">type</span>: <span class="string">'add'</span> &#125;)</span><br><span class="line">        &#125;, <span class="number">1000</span>)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="params">()</span> =&gt;</span> clearInterval(interval)</span><br><span class="line">    &#125;, [])</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">span</span>&gt;</span>&#123;count&#125;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">countReducer</span>(<span class="params">state, action</span>) </span>&#123;</span><br><span class="line">    <span class="comment">/* 类似于 redux */</span></span><br><span class="line">    <span class="keyword">switch</span> (action.type) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">"add"</span>:</span><br><span class="line">            <span class="keyword">return</span> state + <span class="number">1</span></span><br><span class="line">        <span class="keyword">case</span> <span class="string">"minus"</span>:</span><br><span class="line">            <span class="keyword">return</span> state - <span class="number">1</span></span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            <span class="keyword">return</span> state</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> MyCountFunc</span><br></pre></td></tr></table></figure>
<ul>
<li>Hooks –&gt; effect </li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* useEffect */</span></span><br><span class="line">useEffect(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"effect invoked"</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="params">()</span> =&gt;</span> <span class="built_in">console</span>.log(<span class="string">"effect detched"</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* useEffect 的第二个参数[]:</span></span><br><span class="line"><span class="comment">    1. [] 页面渲染的第一次执行，后期不会执行</span></span><br><span class="line"><span class="comment">    2. [count]数组中的每一项发生变化的时候就会调用 useEffect 方法， 类似于Vue中的 watch </span></span><br><span class="line"><span class="comment">    3. 不传， 任何变化都会被出发</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* useLayoutEffect */</span></span><br><span class="line"></span><br><span class="line">useLayoutEffect(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"layout effect invoked"</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="params">()</span> =&gt;</span> <span class="built_in">console</span>.log(<span class="string">"layout effect detched"</span>)</span><br><span class="line">&#125;,[count])</span><br><span class="line"></span><br><span class="line"><span class="comment">/* useLayoutEffect: 虚拟DOM阶段执行， 先于useEffect执行， 不推荐使用  */</span></span><br></pre></td></tr></table></figure>
<ul>
<li>Hooks –&gt; context</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* $ touch lib/my-context.js */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* lib/my-context.js */</span></span><br><span class="line"><span class="keyword">import</span> React <span class="keyword">from</span> <span class="string">'react'</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> React.createContext(<span class="string">''</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* _app.js */</span></span><br><span class="line"><span class="keyword">import</span> MyContext <span class="keyword">from</span> <span class="string">'../lib/my-context'</span></span><br><span class="line"><span class="keyword">import</span> Layout <span class="keyword">from</span> <span class="string">'../components/Layout'</span></span><br><span class="line"></span><br><span class="line">render&#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">        &lt;Layout&gt;</span><br><span class="line">            &lt;MyContext.Provider value=<span class="string">"test"</span>&gt;</span><br><span class="line">                &lt;Component &#123;...pageProps&#125; /&gt;</span><br><span class="line">            &lt;<span class="regexp">/MyContext.Provider&gt;</span></span><br><span class="line"><span class="regexp">        &lt;/</span>Layout&gt;</span><br><span class="line">    )</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* pages/b/js */</span></span><br><span class="line"><span class="keyword">import</span> React, &#123; useState, useEffect, useReducer, useLayoutEffect, useContext &#125; <span class="keyword">from</span> <span class="string">'react'</span></span><br><span class="line"><span class="keyword">import</span> MyContext <span class="keyword">from</span> <span class="string">'../lib/my-context'</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">MyCountFunc</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">const</span> context = useContext(MyContext)</span><br><span class="line">    <span class="built_in">console</span>.log(context) <span class="comment">/* test */</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">p</span>&gt;</span>&#123;context&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>Hooks – ref</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* React */</span></span><br><span class="line"><span class="keyword">constructor</span>(props) &#123;</span><br><span class="line">    <span class="keyword">super</span>(props)</span><br><span class="line">    <span class="keyword">this</span>.span = React.createRef()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">getSpan() &#123;</span><br><span class="line">    <span class="keyword">this</span>.span.current; <span class="comment">/* &lt;span&gt;&lt;/span&gt; */</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">render() &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">span</span> <span class="attr">ref</span>=<span class="string">&#123;this.span&#125;</span>&gt;</span>&#123;this.state.count&#125;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* React Hooks */</span></span><br><span class="line"><span class="keyword">import</span> React, &#123; useState, useEffect, useReducer, useLayoutEffect, useContext, useRef &#125; <span class="keyword">from</span> <span class="string">'react'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> inputRef = useRef()</span><br><span class="line"><span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">Input</span> <span class="attr">ref</span>=<span class="string">&#123;inputRef&#125;</span> <span class="attr">value</span>=<span class="string">&#123;name&#125;</span> <span class="attr">onChange</span>=<span class="string">&#123;(e)</span> =&gt;</span> setName(e.target.value)&#125; /&gt;</span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">console.log(inputRef) /* inputDOM */</span></span><br></pre></td></tr></table></figure>
<ul>
<li>Hooks 优化 memo  useMemo useCallback</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* useMemo 配合 memo 使用 必须是方法组件，class组件不能使用  useCallback是一个简化版的useMemo，只针对于组件方法 */</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>Redux </p>
</blockquote>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    1. 存取公用数据</span></span><br><span class="line"><span class="comment">       单项数据流状态管理工具</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">       action --&gt; reducer --&gt; store --&gt; ui -&gt; action</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    2. Redux 独立于UI框架使用，并非React的定制版，其他UI框架也可以使用</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<ul>
<li>使用 Redux</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    $ npm i redux </span></span><br><span class="line"><span class="comment">    $ touch store/index.js</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">import</span> &#123; createStore &#125; <span class="keyword">from</span> <span class="string">'redux'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> initialState = &#123;</span><br><span class="line">    count: <span class="number">0</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> ADD = <span class="string">"ADD"</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">reducer</span>(<span class="params">state = initialState, action</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(state, action)</span><br><span class="line">    <span class="keyword">switch</span> (action.type) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">"ADD"</span>:</span><br><span class="line">            <span class="keyword">return</span> &#123;</span><br><span class="line">                count: state.count + <span class="number">1</span></span><br><span class="line">            &#125;</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            <span class="keyword">return</span> state</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> store = createStore(reducer, initialState)</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(store)    <span class="comment">/* &#123;count: 0&#125; */</span></span><br><span class="line"><span class="comment">/* store: &#123; </span></span><br><span class="line"><span class="comment">        dispatch:Func(action),</span></span><br><span class="line"><span class="comment">        getState: Func(), </span></span><br><span class="line"><span class="comment">        replaceReducer: Func(nextReducer),</span></span><br><span class="line"><span class="comment">        subscribe: Func(listener), </span></span><br><span class="line"><span class="comment">        Symbol(observable): Func() </span></span><br><span class="line"><span class="comment">    &#125; </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">store.dispatch(&#123; <span class="attr">type</span>: <span class="string">'ADD'</span> &#125;)  </span><br><span class="line"><span class="built_in">console</span>.log(store.getState())  <span class="comment">/* &#123;count: 1&#125; */</span></span><br><span class="line"></span><br><span class="line">store.subscribe(<span class="function"><span class="params">()</span> =&gt;</span>&#123;</span><br><span class="line">    <span class="comment">/* 数据被改变后调用 */</span></span><br><span class="line">    <span class="built_in">console</span>.log(store.getState())</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> store</span><br></pre></td></tr></table></figure>
<ul>
<li>Redux 中的 Reducer</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    纯粹的方法，不应该有任何副作用</span></span><br><span class="line"><span class="comment">    根据 action中的type操作state，返回一个新的对象</span></span><br><span class="line"><span class="comment">    使用combineReducers进行多个reducer的合并</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> &#123; createStore, combineReducers &#125; <span class="keyword">from</span> <span class="string">'redux'</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">reducer</span>(<span class="params">state = initialState, action</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// console.log(state, action)</span></span><br><span class="line">    <span class="keyword">switch</span> (action.type) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">"ADD"</span>:</span><br><span class="line">            <span class="keyword">return</span> &#123;</span><br><span class="line">                count: state.count + <span class="number">1</span></span><br><span class="line">            &#125;</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            <span class="keyword">return</span> state</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">userReducer</span>(<span class="params">state = userInitialState, action</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">switch</span> (action.type) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">"UPDATE_USERNAME"</span>:</span><br><span class="line">            <span class="keyword">return</span> &#123;</span><br><span class="line">                ...state,</span><br><span class="line">                userName: action.name</span><br><span class="line">            &#125;</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            <span class="keyword">return</span> state</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> store = createStore(</span><br><span class="line">    combineReducers(&#123;</span><br><span class="line">        conunt: reducer,</span><br><span class="line">        user: userInitialState</span><br><span class="line">    &#125;),</span><br><span class="line">    &#123;</span><br><span class="line">        count: initialState,</span><br><span class="line">        user: userInitialState</span><br><span class="line">    &#125;</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">store.dispatch(&#123;<span class="attr">type</span>:<span class="string">"UPDATE_USERNAME"</span>, <span class="attr">name</span>:<span class="string">"Jock"</span>&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    &#123;</span></span><br><span class="line"><span class="comment">        count: &#123;</span></span><br><span class="line"><span class="comment">            count: 0</span></span><br><span class="line"><span class="comment">        &#125;,</span></span><br><span class="line"><span class="comment">        user: &#123;</span></span><br><span class="line"><span class="comment">            userName: "Tom"</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<ul>
<li>Redux 中的 action </li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    &#123;type:"", ...&#125; 就是一个对象，根据type 改变state</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* actino create */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span> (<span class="params">num</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;<span class="attr">type</span>: <span class="string">"ADD"</span>, num&#125;</span><br><span class="line">&#125;</span><br><span class="line">store.dispatch(add(<span class="number">12</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 异步action */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    $ npm i redux-thunk  </span></span><br><span class="line"><span class="comment">    redux-thunk 是 redux 的middleware（中间件） 使用applayMiddleware 作为 createStore 的第三个参数</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">import</span> &#123; createStore, combineReducers, applyMiddleware &#125; <span class="keyword">from</span> <span class="string">'redux'</span></span><br><span class="line"><span class="keyword">const</span> store = createStore(</span><br><span class="line">    combineReducers(&#123;</span><br><span class="line">        count: reducer,</span><br><span class="line">        user: userReducer</span><br><span class="line">    &#125;),</span><br><span class="line">    &#123;</span><br><span class="line">        count: initialState,</span><br><span class="line">        user: userInitialState</span><br><span class="line">    &#125;,</span><br><span class="line">    applyMiddleware(reduxThunk)</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">num</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        type: <span class="string">"ADD"</span>,</span><br><span class="line">        num</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">addAsync</span>(<span class="params">num</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function">(<span class="params">dispatch, getState</span>) =&gt;</span> &#123;</span><br><span class="line">        setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">            dispatch(add(num))</span><br><span class="line">        &#125;, <span class="number">1000</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">store.dispatch(addAsync(<span class="number">12</span>))</span><br></pre></td></tr></table></figure>
<ul>
<li>react-redux</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    react 和 redux 的连接器 </span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    $ npm i react-redux </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* _app.js */</span></span><br><span class="line"><span class="keyword">import</span> &#123; Provider &#125; <span class="keyword">from</span> <span class="string">'react-redux'</span></span><br><span class="line">&lt;Provider store=&#123;store&#125;&gt;</span><br><span class="line">    &lt;Component &#123;...pageProps&#125; /&gt;</span><br><span class="line">&lt;<span class="regexp">/Provider&gt;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">/</span>* pages/index.js *<span class="regexp">/</span></span><br><span class="line"><span class="regexp">import &#123; connect &#125; from 'react-redux'</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">const Index = (&#123; counter, username, rename, add &#125;) =&gt; &#123;</span></span><br><span class="line"><span class="regexp">    return (</span></span><br><span class="line"><span class="regexp">        &lt;&gt;</span></span><br><span class="line"><span class="regexp">            &lt;span&gt;counter: &#123;counter&#125;&lt;/</span>span&gt; ---  <span class="xml"><span class="tag">&lt;<span class="name">span</span>&gt;</span>username: &#123;username&#125;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line">            &lt;br /&gt;</span><br><span class="line">            &lt;input value=&#123;username&#125; onChange=&#123;(e) =&gt; rename(e.target.value)&#125; /&gt;</span><br><span class="line">            &lt;br /&gt;</span><br><span class="line">            &lt;button onClick=&#123;() =&gt; add(counter)&#125;&gt;<span class="keyword">do</span> add&lt;<span class="regexp">/button&gt;</span></span><br><span class="line"><span class="regexp">            &lt;br /</span>&gt;</span><br><span class="line">        &lt;<span class="regexp">/&gt;</span></span><br><span class="line"><span class="regexp">    )</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">function mapStateToProps(state) &#123;</span></span><br><span class="line"><span class="regexp">    /</span>* state --&gt; store.getState() *<span class="regexp">/</span></span><br><span class="line"><span class="regexp">    return &#123;</span></span><br><span class="line"><span class="regexp">        counter: state.count.count,</span></span><br><span class="line"><span class="regexp">        username: state.user.userName</span></span><br><span class="line"><span class="regexp">    &#125;</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">function mapDispatchToProps(dispach) &#123;</span></span><br><span class="line"><span class="regexp">    return &#123;</span></span><br><span class="line"><span class="regexp">        add: (num) =&gt; dispach(&#123; type: "ADD", num &#125;),</span></span><br><span class="line"><span class="regexp">        rename: (name) =&gt; dispach(&#123; type: "UPDATE_USERNAME", name &#125;)</span></span><br><span class="line"><span class="regexp">    &#125;</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">export default connect(mapStateToProps, mapDispatchToProps)(Index)</span></span><br></pre></td></tr></table></figure>
<ul>
<li>redux-devtools</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* $ npm i redux-devtools-extension */</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* store.js */</span></span><br><span class="line"><span class="keyword">import</span> &#123; composeWithDevTools &#125; <span class="keyword">from</span> <span class="string">'redux-devtools-extension'</span></span><br><span class="line"><span class="keyword">const</span> store = createStore(</span><br><span class="line">    combineReducers(&#123;</span><br><span class="line">        count: reducer,</span><br><span class="line">        user: userReducer</span><br><span class="line">    &#125;),</span><br><span class="line">    &#123;</span><br><span class="line">        count: initialState,</span><br><span class="line">        user: userInitialState</span><br><span class="line">    &#125;,</span><br><span class="line">    composeWithDevTools(applyMiddleware(reduxThunk))</span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<blockquote>
<p>OAuth 认证和授权</p>
</blockquote>
<ul>
<li>OAuth 概念</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">    认证： 你如何证明你是你自己</span></span><br><span class="line"><span class="comment">    认证方式： 账号密码，邮箱， 手机短信</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure></section>
    <!-- Tags START -->
    
      <div class="tags">
        <span>Tags:</span>
        
  <a href="/tags#NextJs">
    <span class="tag-code">NextJs</span>
  </a>

      </div>
    
    <!-- Tags END -->
    <!-- NAV START -->
    
  <div class="nav-container">
    <!-- reverse left and right to put prev and next in a more logic postition -->
    
      <a class="nav-left" href="/2019/09/17/biancheng/Vue/Vue踩坑集合/">
        <span class="nav-arrow">← </span>
        
          Vue踩坑集合
        
      </a>
    
    
      <a class="nav-right" href="/2019/09/24/biancheng/Element/ElementUI-Vue踩坑集合/">
        
          ElementUI+Vue踩坑集合
        
        <span class="nav-arrow"> →</span>
      </a>
    
  </div>

    <!-- NAV END -->
    <!-- 打赏 START -->
    
    <!-- 打赏 END -->
    <!-- 二维码 START -->
    
      <div class="qrcode">
        <canvas id="share-qrcode"></canvas>
        <p class="notice">扫描二维码，分享此文章</p>
      </div>
    
    <!-- 二维码 END -->
    
      <!-- No Comment -->
    
  </article>
  <!-- Article END -->
  <!-- Catalog START -->
  
  <!-- Catalog END -->
</main>

<script>
  (function () {
    var url = 'http://taoaiyi1108.github.io/2019/09/20/biancheng/Next/NextJs/';
    var banner = ''
    if (banner !== '' && banner !== 'undefined' && banner !== 'null') {
      $('#article-banner').css({
        'background-image': 'url(' + banner + ')'
      })
    } else {
      $('#article-banner').geopattern(url)
    }
    $('.header').removeClass('fixed-header')

     // error image
    $(".markdown-content img").on('error', function() {
      $(this).attr('src', 'http://file.muyutech.com/error-img.png')
      $(this).css({
        'cursor': 'default'
      })
    })

    // zoom image
    $(".markdown-content img").on('click', function() {
      var src = $(this).attr('src')
      if (src !== 'http://file.muyutech.com/error-img.png') {
        var imageW = $(this).width()
        var imageH = $(this).height()
        
        var zoom = ($(window).width() * 0.95 / imageW).toFixed(2)
        zoom = zoom < 1 ? 1 : zoom
        zoom = zoom > 2 ? 2 : zoom
        var transY = (($(window).height() - imageH) / 2).toFixed(2)

        $('body').append('<div class="image-view-wrap"><div class="image-view-inner"><img src="'+ src +'" /></div></div>')
        $('.image-view-wrap').addClass('wrap-active')
        $('.image-view-wrap img').css({
          'width': `${imageW}`,
          'transform': `translate3d(0, ${transY}px, 0) scale3d(${zoom}, ${zoom}, 1)`
        })
        $('html').css('overflow', 'hidden')

        $('.image-view-wrap').on('click', function() {
          $(this).remove()
          $('html').attr('style', '')
        })
      }
    })

    // qrcode
    var qr = new QRious({
      element: document.getElementById('share-qrcode'),
      value: document.location.href
    });

    // gitment
    var gitmentConfig = "taoaiyi1108";
    if (gitmentConfig !== 'undefined') {
      var gitment = new Gitment({
        id: "NextJs",
        owner: "taoaiyi1108",
        repo: "taoaiyi1108.github.io",
        oauth: {
          client_id: "0f87e490e00ee3fd87ef",
          client_secret: "4a9d2b148e7971c2201ad12131ce8bf8159ccd2e"
        },
        theme: {
          render(state, instance) {
            const container = document.createElement('div')
            container.lang = "en-US"
            container.className = 'gitment-container gitment-root-container'
            container.appendChild(instance.renderHeader(state, instance))
            container.appendChild(instance.renderEditor(state, instance))
            container.appendChild(instance.renderComments(state, instance))
            container.appendChild(instance.renderFooter(state, instance))
            return container;
          }
        }
      })
      gitment.render(document.getElementById('comments'))
    }
  })();
</script>

<script>
  var disqus_shortname = '';
  
  var disqus_url = 'http://taoaiyi1108.github.io/2019/09/20/biancheng/Next/NextJs/';
  
  (function(){
    var dsq = document.createElement('script');
    dsq.type = 'text/javascript';
    dsq.async = true;
    dsq.src = '//go.disqus.com/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  })();
</script>

    <div class="scroll-top">
  <span class="arrow-icon"></span>
</div>
    <footer class="app-footer">
  <p class="copyright">
    &copy; 2019 火骑小龙龙 | Proudly powered by <a href="https://hexo.io" target="_blank">Hexo</a>
    <br>
    感谢大神 <a href="https://github.com/yanm1ng" target="_blank">yanm1ng</a> 对本博客的技术支持
  </p>
</footer>

<script>
  function async(u, c) {
    var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
    s.parentNode.insertBefore(o, s);
  }
</script>
<script>
  async("//cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js", function(){
    FastClick.attach(document.body);
  })
</script>

<script>
  var hasLine = 'true';
  async("//cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js", function(){
    $('figure pre').each(function(i, block) {
      var figure = $(this).parents('figure');
      if (hasLine === 'false') {
        figure.find('.gutter').hide();
      }
      var lang = figure.attr('class').split(' ')[1] || 'code';
      var codeHtml = $(this).html();
      var codeTag = document.createElement('code');
      codeTag.className = lang;
      codeTag.innerHTML = codeHtml;
      $(this).attr('class', '').empty().html(codeTag);
      figure.attr('data-lang', lang.toUpperCase());
      hljs.highlightBlock(block);
    });
  })
</script>
<!-- Baidu Tongji -->

<script src="/js/script.js"></script>
  </body>
</html>